package cn.iocoder.yudao.module.design.service.purchase;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.design.controller.admin.purchase.vo.PurchaseCreateReqVO;
import cn.iocoder.yudao.module.design.controller.admin.purchase.vo.PurchaseExportReqVO;
import cn.iocoder.yudao.module.design.controller.admin.purchase.vo.PurchasePageReqVO;
import cn.iocoder.yudao.module.design.controller.admin.purchase.vo.PurchaseUpdateReqVO;
import cn.iocoder.yudao.module.design.convert.purchase.PurchaseConvert;
import cn.iocoder.yudao.module.design.dal.dataobject.pic.PicDO;
import cn.iocoder.yudao.module.design.dal.dataobject.purchase.PurchaseDO;
import cn.iocoder.yudao.module.design.dal.dataobject.userflowrel.UserFlowRelDO;
import cn.iocoder.yudao.module.design.dal.mysql.pic.PicMapper;
import cn.iocoder.yudao.module.design.dal.mysql.purchase.PurchaseMapper;
import cn.iocoder.yudao.module.design.dal.mysql.userflowrel.UserFlowRelMapper;
import cn.iocoder.yudao.module.design.service.pic.PicService;
import cn.iocoder.yudao.module.design.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.design.enums.design.PicSourceTypeEnum;
import cn.iocoder.yudao.module.design.enums.design.PicUploadTypeEnum;
import cn.iocoder.yudao.module.design.enums.design.UserRelStatusCdEnum;
import cn.iocoder.yudao.module.design.enums.user.DesignUserRoleEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.design.enums.ErrorCodeConstants.PURCHASE_NOT_EXISTS;

/**
 * 采购清单 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class  PurchaseServiceImpl implements PurchaseService {

    @Resource
    private PurchaseMapper purchaseMapper;

    @Resource
    private UserFlowRelMapper userFlowRelMapper;

    @Resource
    private PicMapper picMapper;

    @Resource
    private PicService picService;

    @Override
    public Long createPurchase(PurchaseCreateReqVO createReqVO) {
        // 插入
        PurchaseDO purchase = PurchaseConvert.INSTANCE.convert(createReqVO);
        purchase.setStatusCd("0");
        purchase.setDeleted(false);
        purchaseMapper.insert(purchase);

        //10 附件 11合同  12图纸 13材料清单 14家电清单
        // 保存图片
        PicDO picDo = new PicDO();
        picDo.setHouseId(purchase.getHouseId());
        picDo.setFlowId(purchase.getFlowId());
        picDo.setItemId(purchase.getId());
        picDo.setUploadType("0");
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_010.getCode());
        // 保存附件
        picService.savePicData(picDo,createReqVO.getFileList());
        // 保存合同
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_011.getCode());
        picService.savePicData(picDo,createReqVO.getContractFile());
        // 保存图纸
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_012.getCode());
        picService.savePicData(picDo,createReqVO.getDrawList());
        // 保存清单清单
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_013.getCode());
        picService.savePicData(picDo,createReqVO.getPurchaseList());
        // 返回
        return purchase.getId();
    }

    @Override
    public void updatePurchase(PurchaseUpdateReqVO updateReqVO) {
        // 校验存在
        this.validatePurchaseExists(updateReqVO.getId());
        // 更新
        PurchaseDO updateObj = PurchaseConvert.INSTANCE.convert(updateReqVO);
        purchaseMapper.updateById(updateObj);

        // 保存图片
        PicDO picDo = new PicDO();
        picDo.setHouseId(updateObj.getHouseId());
        picDo.setFlowId(updateObj.getFlowId());
        picDo.setItemId(updateObj.getId());
        picDo.setUploadType(PicUploadTypeEnum.PIC_UPLOAD_TYPE_ENUM_0.getCode());
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_010.getCode());
        // 保存附件
        picService.savePicData(picDo,updateReqVO.getFileList());
        // 保存合同
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_011.getCode());
        picService.savePicData(picDo,updateReqVO.getContractFile());
        // 保存图纸
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_012.getCode());
        picService.savePicData(picDo,updateReqVO.getDrawList());
        // 保存清单清单
        picDo.setSourceType(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_013.getCode());
        picService.savePicData(picDo,updateReqVO.getPurchaseList());

    }

    /**
     * 更新采购清单
     *
     * @param updateReqVO 更新信息
     */
    @Override
    public void updatePurchaseStatus(PurchaseUpdateReqVO updateReqVO) {
        // 校验存在
        this.validatePurchaseExists(updateReqVO.getId());
        PurchaseDO purchaseDO = purchaseMapper.selectById(updateReqVO.getId());
        purchaseDO.setStatusCd(updateReqVO.getStatusCd());

        purchaseMapper.updateById(purchaseDO);
    }

    @Override
    public void deletePurchase(Long id) {
        // 校验存在
        this.validatePurchaseExists(id);
        // 删除
        purchaseMapper.deleteById(id);
    }

    private void validatePurchaseExists(Long id) {
        if (purchaseMapper.selectById(id) == null) {
            throw exception(PURCHASE_NOT_EXISTS);
        }
    }

    @Override
    public PurchaseDO getPurchase(Long id) {
        // 根据id 查询对应的流程id
        PurchaseDO purchaseDO = purchaseMapper.selectById(id);
        // 判断当前登录人是否为 项目内关联人
        final Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // 先判断当前操作人是否是项目的关联人(状态正常)  不是 报错
        QueryWrapper<UserFlowRelDO> queryUserRel = new QueryWrapper<>();
        queryUserRel.eq("user_id",loginUserId);
        queryUserRel.eq("flow_id",purchaseDO.getFlowId());
        queryUserRel.eq("status", UserRelStatusCdEnum.USER_REL_STATUS_CD_1.getCode());

        final Long aLong = userFlowRelMapper.selectCount(queryUserRel);
        // 根据流程id 判断是否是流程的关联人
        if(aLong<=0){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.NO_AUTHORITY_OPTION_BY_PROJECT);
//            throw new NullPointerException("非本项目人员无权限操作");
        }

        return purchaseDO;
    }

    @Override
    public List<PurchaseDO> getPurchaseList(Collection<Long> ids) {
        return purchaseMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<PurchaseDO> getPurchasePage(PurchasePageReqVO pageReqVO) {
        return purchaseMapper.selectPage(pageReqVO);
    }

    @Override
    public List<PurchaseDO> getPurchaseList(PurchaseExportReqVO exportReqVO) {
        return purchaseMapper.selectList(exportReqVO);
    }

    /**
     * 根据flowId获取货物清单
     * @param flowId
     * @param statusCd
     * @return
     */
    @Override
    public List<Map> getPurchaseListByFlowId(Long flowId,String statusCd) {

        // 判断当前登录人是否为 项目内关联人
        final Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // 先判断当前操作人是否是项目的关联人(状态正常)  不是 报错
        QueryWrapper<UserFlowRelDO> queryUserRel = new QueryWrapper<>();
        queryUserRel.eq("user_id",loginUserId);
        queryUserRel.eq("flow_id",flowId);
        queryUserRel.eq("status", UserRelStatusCdEnum.USER_REL_STATUS_CD_1.getCode());
        final Long aLong = userFlowRelMapper.selectCount(queryUserRel);

        if(aLong<=0){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.NO_AUTHORITY_OPTION_BY_PROJECT);
//            throw new NullPointerException("非本项目人员无权限操作");
        }
        List<Map> purchaseDOS = purchaseMapper.getPurchaseListByFlowId(flowId,statusCd);


        return purchaseDOS;
    }


    /**
     * 根据flowId获取货物清单
     * @param flowId
     * @param statusCd
     * @return
     */
    @Override
    public Map getPurchaseListInfoByFlowId(Long flowId,String statusCd) {

        List<Map> purchaseDOS = getPurchaseListByFlowId(flowId,statusCd);
        Map<String,Object> result = new HashMap<>();
        // 查询供应商信息
        Map supplierInfo = userFlowRelMapper.selectUserRelInfoByRoleId(flowId, DesignUserRoleEnum.SUPPLIER.getRoleId());
        String supplierName = null ;
        Long supplierId = null ;
        String supplierMobile = null ;
        Long flowId1 = null ;
        Long houseId = null ;
    // 供应商信息
        if(ObjectUtil.isNotNull(supplierInfo)){
            supplierName = (String) supplierInfo.get("nickname");
            supplierId = (Long) supplierInfo.get("id");
            supplierMobile = (String) supplierInfo.get("mobile");
            flowId1 = (Long) supplierInfo.get("flowId");

            houseId = (Long) supplierInfo.get("houseId");
        }
        result.put("supplierName",supplierName);
        result.put("supplierId",supplierId);
        result.put("supplierMobile",supplierMobile);

        result.put("flowId",flowId1);
        result.put("houseId",houseId);
        // 负责人信息
        Map principalInfo = userFlowRelMapper.selectUserRelInfoByRoleId(flowId, DesignUserRoleEnum.PRINCIPAL.getRoleId());
        String principalName = null;
        Long principalId = null;
        String principalMobile = null;
        if(ObjectUtil.isNotNull(principalInfo)){
            principalName= (String) principalInfo.get("nickname");
            principalId= (Long) principalInfo.get("id");
            principalMobile= (String) principalInfo.get("mobile");
        }
        result.put("principalName",principalName);
        result.put("principalId",principalId);
        result.put("principalMobile",principalMobile);

        // 查询文件信息
        for (Map purchase: purchaseDOS   ) {
            final Long id = (Long) purchase.get("id");
            PicDO picDO = new PicDO();
            Long houseId1 = (Long) purchase.get("houseId");
            Long flowId2 = (Long) purchase.get("flowId");

            picDO.setHouseId(houseId1);
            picDO.setFlowId(flowId2);
            picDO.setItemId(id);

            picDO.setUploadType(PicUploadTypeEnum.PIC_UPLOAD_TYPE_ENUM_0.getCode());
            picDO.setStatus("0");
            List<PicDO> picData = picService.getPicData(picDO);
            // 查询当前item 所有附件
            Map<String, List<PicDO>> collect = picData.stream()
                    .collect(Collectors.groupingBy(item -> item.getSourceType()));

            // 保存附件
            purchase.put("fileList",collect.get(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_010.getCode()));
            // 保存合同
            purchase.put("contractFile",collect.get(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_011.getCode()));
            // 保存图纸
            purchase.put("drawList",collect.get(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_012.getCode()));
            // 保存清单清单
            purchase.put("purchaseList",collect.get(PicSourceTypeEnum.PIC_SOURCE_TYPE_ENUM_013.getCode()));
        }
        result.put("purchaseList",purchaseDOS);
        return result;
    }

    /**
     * 更新采购清单状态
     *
     * @param id 编号
     */
    @Override
    public void modifyPurchaseStatusCd(Long id) {
        // 根据id 查询对应的流程id
        PurchaseDO purchaseDO = purchaseMapper.selectById(id);
        // 判断当前登录人是否为 项目内关联人
        final Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // 先判断当前操作人是否是项目的关联人(状态正常)  不是 报错
        QueryWrapper<UserFlowRelDO> queryUserRel = new QueryWrapper<>();
        queryUserRel.eq("user_id",loginUserId);
        queryUserRel.eq("flow_id",purchaseDO.getFlowId());
        queryUserRel.eq("status", UserRelStatusCdEnum.USER_REL_STATUS_CD_1.getCode());

        final Long aLong = userFlowRelMapper.selectCount(queryUserRel);
        // 根据流程id 判断是否是流程的关联人
        if(aLong<=0){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.NO_AUTHORITY_OPTION_BY_PROJECT);
//            throw new NullPointerException("非本项目人员无权限操作");
        }
        // 计算货物下一状态
        calculationPurchaseStatus(purchaseDO);
        purchaseMapper.updateById(purchaseDO);
    }

    /**
     * 计算货物状态流转
     * @param purchaseDO
     */
    void calculationPurchaseStatus(PurchaseDO purchaseDO ){
        String statusCd = purchaseDO.getStatusCd() ;
        switch (purchaseDO.getStatusCd()) {
            case "0":
                statusCd ="1";
                break;
            case "1" :
                statusCd ="2";
                break;
            default:
                break;
        }
        purchaseDO.setStatusCd(statusCd);
    }






}
